package com.dony.order.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dony.common.utils.StringUtils;
import com.dony.order.domain.Order;
import com.dony.order.mapper.OrderMapper;
import com.dony.order.service.IBlackRecordService;
import com.dony.order.service.IOrderService;
import com.dony.shop.domain.ShopeeShop;
import com.dony.shop.domain.vo.PushVo;
import com.dony.shop.service.IShopeeShopService;
import com.dony.shop.util.ShopeeUtil;
import com.github.yulichang.base.MPJBaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单Service业务层处理
 *
 * @author dony
 * @date 2022-09-07
 */
@Slf4j
@Service("orderService")
public class OrderServiceImpl extends MPJBaseServiceImpl<OrderMapper, Order> implements IOrderService {

    @Autowired
    ShopeeUtil shopeeUtil;
    @Resource
    IShopeeShopService shopService;
    @Resource
    IBlackRecordService blackRecordService;
    @Resource
    ThreadPoolTaskExecutor executor;

    /**
     * @return
     */
    public Boolean syncOrderByTimer() {
        List<ShopeeShop> shops = shopService.list();
        shops.forEach(shop -> {
            executor.execute(() -> {
                syncOrderByShop(shop.getShopId(), 4);
            });
        });
        log.info("订单同步完成！");
        return true;
    }

    @Override
    public Boolean syncOrder() {
        List<ShopeeShop> shops = shopService.list();
        shops.forEach(shop -> syncOrderByShop(shop.getShopId()));
        log.info("订单同步完成！");
        return true;
    }

    @Override
    public Boolean syncOrderByMerchant(Long merchantId) {
        //查询当前商户下面的所有店铺
        List<ShopeeShop> shops = shopService.list(new QueryWrapper<ShopeeShop>().eq("merchant_id", merchantId));
        shops.forEach(shop -> syncOrderByShop(shop.getShopId()));
        return true;
    }

    @Override
    public Boolean syncOrderByShop(Long shopId) {
        executor.execute(() -> {
            syncOrderByShop(shopId, 1);
        });
        return true;
    }

    /**
     * 【定时任务】每小时同步一次订单 //后期调整频率
     */

    /**
     * 同步几个半月订单
     *
     * @param shopId
     * @param times  几个15天
     * @return
     */
    public void syncOrderByShop(Long shopId, int times) {
        //当前时间
        long timestamp = System.currentTimeMillis() / 1000L;
        //15天前的时间
        long gap = 15 * 24 * 60 * 60;
        for (int i = 0; i < times; i++) {
            long thisTimeFrom = timestamp - gap * (i + 1);
            long thisTimeTo = timestamp - gap * i;
            syncOrderShopList(shopId, thisTimeFrom, thisTimeTo);
        }
    }


    /**
     * 根据时间同步订单列表
     *
     * @param shopId
     * @param thisTimeFrom
     * @param thisTimeTo
     */
    private void syncOrderShopList(Long shopId, long thisTimeFrom, long thisTimeTo) {
        //log.info("开始查询订单->syncOrderList");
        boolean more = false;
        String cursor = "";
        do {
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("time_range_field", "create_time");
            paramMap.put("time_from", thisTimeFrom);
            paramMap.put("time_to", thisTimeTo);
            paramMap.put("page_size", 50);
            paramMap.put("cursor", cursor);

            JSONObject response = shopeeUtil.shopGetHandler("/api/v2/order/get_order_list", shopId, paramMap);
            if (response == null) {
                more = false;
                continue;
            }
            more = response.getBoolean("more");
            cursor = response.getString("next_cursor");
            List<JSONObject> orderList = response.getList("order_list", JSONObject.class);
            List<String> orderSnList = orderList.stream().map(order -> order.getString("order_sn")).collect(Collectors.toList());
            //查询子表
            if (orderSnList == null || orderSnList.size() == 0) {
                continue;
            }
            syncOrder(shopId, orderSnList);
        } while (more);
    }


    /**
     * 同步订单
     *
     * @param shopId
     * @param sns
     * @return
     */
    public List<Order> syncOrder(Long shopId, List<String> sns) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("order_sn_list", sns);
        paramMap.put("response_optional_fields", "total_amount,shipping_carrier,payment_method," + "estimated_shipping_fee,message_to_seller,buyer_user_id,buyer_username,recipient_address," + "actual_shipping_fee,actual_shipping_fee,note,pay_time,buyer_cancel_reason,cancel_by,cancel_reason," + "actual_shipping_fee,cod,goods_to_declare,note_update_time,pickup_done_time,item_list");
        JSONObject response = shopeeUtil.shopGetHandler("/api/v2/order/get_order_detail", shopId, paramMap);
        if (response == null) {
            return null;
        }
        List<JSONObject> orderList = response.getList("order_list", JSONObject.class);

        ShopeeShop shop = shopService.getByShopId(shopId);
        List<Order> orders = orderList.stream().map(o -> {
            Order order = this.getOne(new QueryWrapper<Order>().eq("order_sn", o.getString("order_sn")));
            if (order == null) {
                order = new Order();
                order.setOrderSn(o.getString("order_sn"));
            }
            order.setShopId(shopId);
            //设置店铺其他信息
            if (shop != null) {
                order.setShopName(StringUtils.isNotEmpty(shop.getDefindName()) ? shop.getDefindName() : shop.getShopName());
                order.setMerchantId(shop.getMerchantId());
                order.setTenantId(shop.getTenantId());
            }
            order.setRegion(o.getString("region"));
            order.setCurrency(o.getString("currency"));
            order.setTotalAmount(o.getFloat("total_amount"));
            //获取收入金额
            order.setIncome(this.getIncomeByOrderSn(shopId, order.getOrderSn()));
            order.setOrderStatus(o.getString("order_status"));
            order.setShippingCarrier(o.getString("shipping_carrier"));
            order.setPaymentMethod(o.getString("payment_method"));
            order.setEstimatedShippingFee(o.getFloat("estimated_shipping_fee"));
            order.setMessageToSeller(o.getString("message_to_seller"));
            //处理时间信息
            if (o.getLong("create_time") != null) {
                order.setCreateTime(new Date(o.getLong("create_time") * 1000L));
            }
            if (o.getLong("update_time") != null) {
                order.setUpdateTime(new Date(o.getLong("update_time") * 1000L));
            }
            order.setDaysToShip(o.getInteger("days_to_ship"));
            if (o.getLong("ship_by_date") != null) {
                order.setShipByDate(new Date(o.getLong("ship_by_date") * 1000L));
            }
            order.setBuyerUserId(o.getLong("buyer_user_id"));
            order.setBuyerUsername(o.getString("buyer_username"));
            //收货地址信息
            JSONObject address = o.getJSONObject("recipient_address");
            if (address != null) {
                order.setRecipientName(address.getString("name"));
                order.setRecipientPhone(address.getString("phone"));
                order.setRecipientTown(address.getString("town"));
                order.setRecipientDistrict(address.getString("district"));
                order.setRecipientCity(address.getString("city"));
                order.setRecipientState(address.getString("state"));
                order.setRecipientRegion(address.getString("region"));
                order.setRecipientZipcode(address.getString("zipcode"));
                order.setRecipientFullAddress(address.getString("full_address"));
            }
            order.setActualShippingFee(o.getFloat("actual_shipping_fee"));
            order.setNote(o.getString("note"));
            if (o.getLong("pay_time") != null) {
                order.setPayTime(new Date(o.getLong("pay_time") * 1000L));
            }
            order.setBuyerCancelReason(o.getString("buyer_cancel_reason"));
            order.setCancelBy(o.getString("cancel_by"));
            order.setCancelReason(o.getString("cancel_reason"));
            order.setCod(o.getBoolean("cod"));
            order.setGoodsToDeclare(o.getBoolean("goods_to_declare"));
            if (o.getLong("note_update_time") != null) {
                order.setNoteUpdateTime(new Date(o.getLong("note_update_time") * 1000L));
            }
            if (o.getLong("pickup_done_time") != null) {
                order.setPickupDoneTime(new Date(o.getLong("pickup_done_time") * 1000L));
            }
            //商品信息
            order.setItemList(o.getJSONArray("item_list").toString());

            //查询是否是黑名单用户
            order.setBlack(blackRecordService.isBlackOrder(order.getBuyerUserId()));

            //没有设置状态，则开始纳入管理
            if (order.getSysStatus() == null) {
                if (StringUtils.containsAny(order.getOrderStatus(), "READY_TO_SHIP", "RETRY_SHIP", "IN_CANCEL", "PROCESSED")) {
                    order.setSysStatus(1);
                }
            } else {
                if (StringUtils.containsAny(order.getOrderStatus(), "SHIPPED", "TO_CONFIRM_RECEIVE", "COMPLETED")) {
                    order.setSysStatus(6);
                }
                if (StringUtils.containsAny(order.getOrderStatus(), "CANCELLED", "TO_RETURN")) {
                    order.setSysStatus(-1);
                }
            }
            //处理取消的订单
            return order;
        }).collect(Collectors.toList());
        this.saveOrUpdateBatch(orders);
        return orders;
    }


    @Override
    public Float getIncomeByOrderSn(Long shopId, String orderSn) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("order_sn", orderSn);
        JSONObject response = shopeeUtil.shopGetHandler("/api/v2/payment/get_escrow_detail", shopId, paramMap);
        if (response == null) {
            return null;
        }
        JSONObject orderIncome = response.getJSONObject("order_income");
        return orderIncome.getFloat("escrow_amount_pri");
    }

    @Override
    public Boolean handleShopeePush(PushVo pushVo) {
        String status = pushVo.getData().getString("status");
        log.info("接收到了shopee的订单状态推送,店铺Id:{},订单号：{},订单状态：{}", pushVo.getShop_id(), pushVo.getData().getString("ordersn"), status);
        //这里可能出现多线程的问题
        executor.execute(() -> {
            syncOrder(pushVo.getShop_id(), Arrays.asList(pushVo.getData().getString("ordersn")));
        });
        return true;
    }

}
